﻿using Amazon.S3.Model;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Minio.Exceptions;
using Newtonsoft.Json;

namespace Files_Upload.API.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class MinioController : ControllerBase
    {
        private readonly MinioHelper minioHelper;
        private readonly ILogger<MinioController> _logger;

        public MinioController(ILogger<MinioController> logger, MinioHelper minioHelper)
        {
            _logger = logger;
            this.minioHelper = minioHelper;
        }
         
        /// <summary>
        /// 初始化文件获取uploadid
        /// </summary>
        /// <param name="KeyName"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<string> InitMultipartChunkUploadFile(string KeyName)
        {
            var initResponse = await minioHelper.InitMultipartChunkUploadFile("zhangzong", DateTime.Now.ToString("yyyy-MM-dd") + "/" + KeyName);
            return initResponse;
        }

        /// <summary>
        /// 查询上传分片列表
        /// </summary>
        /// <param name="Name">文件名</param>
        /// <param name="UploadId">上传ID</param>
        /// <returns>返回上传分片列表</returns>
        [HttpGet("/minio/ListPartsFile")]
        public async Task<IActionResult> ListPartsFile(string Name, string? UploadId = "")
        {
            List<PartDetail> listPartResponse = new List<PartDetail>();
            try
            {
                listPartResponse = await minioHelper.ListPartsUploadInfo("zhangzong", DateTime.Now.ToString("yyyy-MM-dd") + "/" + Name, UploadId);
                _logger.LogInformation("查询上传分片列表: {0}", JsonConvert.SerializeObject(listPartResponse));
            }
            catch (MinioException e)
            {
                _logger.LogError("查询上传分片列表错误: {0}", e.Message);
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(new { UploadId, listPartResponse });
        }

        /// <summary>
        /// 合并分片
        /// </summary>
        /// <param name="Name">文件名</param>
        /// <param name="UploadId">上传ID</param>
        /// <param name="partETagList">分片ETag列表</param>
        /// <returns>返回合并结果</returns>
        [HttpPost("/minio/ChunkMultipartUpload")]
        public async Task<IActionResult> ChunkMultipartUpload(dto dto)
        {
            CompleteMultipartUploadResponse compResponse = new CompleteMultipartUploadResponse();
            try
            {
                // 完成分片上传
                compResponse = await minioHelper.CompleteMultipartUploadFile("zhangzong", DateTime.Now.ToString("yyyy-MM-dd") + "/" + dto.Name, dto.UploadId, dto.partETagList);
                _logger.LogInformation("分片上传: {0}", JsonConvert.SerializeObject(compResponse.Key));
            }
            catch (MinioException e)
            {
                _logger.LogError("文件上传错误: {0}", e.Message);
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }

            return Ok(new { compResponse });
        }

        /// <summary>
        /// 上传分片
        /// </summary>
        /// <param name="files">文件</param>
        /// <param name="ID">文件ID</param>
        /// <param name="Name">文件名</param>
        /// <param name="Size">文件大小</param>
        /// <param name="partSize">分片大小</param>
        /// <param name="ChunkCount">当前第几片</param>
        /// <param name="UploadId">上传ID</param>
        /// <returns>返回上传结果</returns>
        [HttpPost("/minio/ChunkUploadFile")]
        public async Task<IActionResult> ChunkUploadFile(IFormFile files, [FromForm] string Name, [FromForm] long Size, [FromForm] long partSize, [FromForm] int ChunkCount, [FromForm] string? UploadId = "")
        {
            List<PartETag> partETagList = new List<PartETag>();
            try
            {
                // 定义输入流
                Stream inputStream = files.OpenReadStream();
                if (string.IsNullOrWhiteSpace(UploadId))
                {
                    // 初始化分片上传，得到UploadId
                    UploadId = await minioHelper.InitMultipartChunkUploadFile("zhangzong", DateTime.Now.ToString("yyyy-MM-dd") +"/"+ Name);
                }
                PartETag partETag = await minioHelper.ChunkUploadAsync("zhangzong", DateTime.Now.ToString("yyyy-MM-dd") + "/" + Name, UploadId, ChunkCount, partSize, inputStream);
                partETagList.Add(partETag);
            }
            catch (MinioException e)
            {
                _logger.LogError("文件上传错误: {0}", e.Message);
                return StatusCode(StatusCodes.Status500InternalServerError, e.Message);
            }
            catch (InvalidOperationException e)
            {
                _logger.LogError("无效的上传ID: {0}", e.Message);
                return StatusCode(StatusCodes.Status400BadRequest, e.Message);
            }

            return Ok(new { UploadId, partETagList, Name });
        }
        public class dto
        {
            public string Name { get; set; }
            public string UploadId { get; set; }
            public List<PartETag> partETagList { get; set; }
        }
    }
}